﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Avalonia.Win32.DirectX
{
    internal enum D3D_FEATURE_LEVEL
    {
        D3D_FEATURE_LEVEL_1_0_CORE = 0x1000,

        D3D_FEATURE_LEVEL_9_1 = 0x9100,

        D3D_FEATURE_LEVEL_9_2 = 0x9200,

        D3D_FEATURE_LEVEL_9_3 = 0x9300,

        D3D_FEATURE_LEVEL_10_0 = 0xa000,

        D3D_FEATURE_LEVEL_10_1 = 0xa100,

        D3D_FEATURE_LEVEL_11_0 = 0xb000,

        D3D_FEATURE_LEVEL_11_1 = 0xb100,

        D3D_FEATURE_LEVEL_12_0 = 0xc000,

        D3D_FEATURE_LEVEL_12_1 = 0xc100,

        D3D_FEATURE_LEVEL_12_2 = 0xc200,
    }

    internal enum D3D11_RESOURCE_DIMENSION
    {
        D3D11_USAGE_DEFAULT = 0,

        D3D11_USAGE_IMMUTABLE = 1,

        D3D11_USAGE_DYNAMIC = 2,

        D3D11_USAGE_STAGING = 3,
    }

    internal enum D3D11_USAGE
    {
        D3D11_USAGE_DEFAULT = 0,

        D3D11_USAGE_IMMUTABLE = 1,

        D3D11_USAGE_DYNAMIC = 2,

        D3D11_USAGE_STAGING = 3,
    }
    
    [Flags]
    internal enum D3D11_RESOURCE_MISC_FLAG
    {
        D3D11_RESOURCE_MISC_GENERATE_MIPS                   = 0x00000001,
        D3D11_RESOURCE_MISC_SHARED                          = 0x00000002,
        D3D11_RESOURCE_MISC_TEXTURECUBE                     = 0x00000004,
        D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS               = 0x00000010,
        D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS          = 0x00000020,
        D3D11_RESOURCE_MISC_BUFFER_STRUCTURED               = 0x00000040,
        D3D11_RESOURCE_MISC_RESOURCE_CLAMP                  = 0x00000080,
        D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX               = 0x00000100,
        D3D11_RESOURCE_MISC_GDI_COMPATIBLE                  = 0x00000200,
        D3D11_RESOURCE_MISC_SHARED_NTHANDLE                 = 0x00000800,
        D3D11_RESOURCE_MISC_RESTRICTED_CONTENT              = 0x00001000,
        D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE        = 0x00002000,
        D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE_DRIVER = 0x00004000,
        D3D11_RESOURCE_MISC_GUARDED                         = 0x00008000,
        D3D11_RESOURCE_MISC_TILE_POOL                       = 0x00020000,
        D3D11_RESOURCE_MISC_TILED                           = 0x00040000,
        D3D11_RESOURCE_MISC_HW_PROTECTED                    = 0x00080000,
    }
    
    [Flags]
    internal enum D3D11_BIND_FLAG
    {
        D3D11_BIND_VERTEX_BUFFER = 0x00000001,
        D3D11_BIND_INDEX_BUFFER = 0x00000002,
        D3D11_BIND_CONSTANT_BUFFER = 0x00000004,
        D3D11_BIND_SHADER_RESOURCE = 0x00000008,
        D3D11_BIND_STREAM_OUTPUT = 0x00000010,
        D3D11_BIND_RENDER_TARGET = 0x00000020,
        D3D11_BIND_DEPTH_STENCIL = 0x00000040,
        D3D11_BIND_UNORDERED_ACCESS = 0x00000080,
        D3D11_BIND_DECODER = 0x00000200,
        D3D11_BIND_VIDEO_ENCODER = 0x00000400,
    }
    
    internal enum DXGI_SWAP_EFFECT
    {
        DXGI_SWAP_EFFECT_DISCARD = 0,

        DXGI_SWAP_EFFECT_SEQUENTIAL = 1,

        DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3,

        DXGI_SWAP_EFFECT_FLIP_DISCARD = 4,
    }
    
    [Flags]
    internal enum DXGI_SWAP_CHAIN_FLAG
    {
        DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1,

        DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2,

        DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4,

        DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8,

        DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16,

        DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32,

        DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64,

        DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128,

        DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256,

        DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512,

        DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 1024,

        DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 2048,

        DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 4096,
    }
    
    internal enum DXGI_SCALING
    {
        DXGI_SCALING_STRETCH = 0,

        DXGI_SCALING_NONE = 1,

        DXGI_SCALING_ASPECT_RATIO_STRETCH = 2,
    }

    internal enum DXGI_RESIDENCY
    {
        DXGI_RESIDENCY_FULLY_RESIDENT = 1,

        DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2,

        DXGI_RESIDENCY_EVICTED_TO_DISK = 3,
    }

    internal enum DXGI_MODE_ROTATION
    {
        DXGI_MODE_ROTATION_UNSPECIFIED = 0,

        DXGI_MODE_ROTATION_IDENTITY = 1,

        DXGI_MODE_ROTATION_ROTATE90 = 2,

        DXGI_MODE_ROTATION_ROTATE180 = 3,

        DXGI_MODE_ROTATION_ROTATE270 = 4,
    }

    internal enum DXGI_ALPHA_MODE
    {
        DXGI_ALPHA_MODE_UNSPECIFIED = 0,

        DXGI_ALPHA_MODE_PREMULTIPLIED = 1,

        DXGI_ALPHA_MODE_STRAIGHT = 2,

        DXGI_ALPHA_MODE_IGNORE = 3,

        DXGI_ALPHA_MODE_FORCE_DWORD = (unchecked((int)0xffffffff)),
    }

    internal enum D3D_DRIVER_TYPE
    {
        D3D_DRIVER_TYPE_UNKNOWN = 0,
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_REFERENCE,
        D3D_DRIVER_TYPE_NULL,
        D3D_DRIVER_TYPE_SOFTWARE,
        D3D_DRIVER_TYPE_WARP
    }

    internal enum DXGI_ERROR : uint
    {
        DXGI_ERROR_ACCESS_DENIED = 0x887A002B,
        DXGI_ERROR_ACCESS_LOST = 0x887A0026,
        DXGI_ERROR_ALREADY_EXISTS = 0x887A0036,
        DXGI_ERROR_CANNOT_PROTECT_CONTENT = 0x887A002A,
        DXGI_ERROR_DEVICE_HUNG = 0x887A0006,
        DXGI_ERROR_DEVICE_REMOVED = 0x887A0005,
        DXGI_ERROR_DEVICE_RESET = 0x887A0007,
        DXGI_ERROR_DRIVER_INTERNAL_ERROR = 0x887A0020,
        DXGI_ERROR_FRAME_STATISTICS_DISJOINT = 0x887A000B,
        DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE = 0x887A000C,
        DXGI_ERROR_INVALID_CALL = 0x887A0001,
        DXGI_ERROR_MORE_DATA = 0x887A0003,
        DXGI_ERROR_NAME_ALREADY_EXISTS = 0x887A002C,
        DXGI_ERROR_NONEXCLUSIVE = 0x887A0021,
        DXGI_ERROR_NOT_CURRENTLY_AVAILABLE = 0x887A0022,
        DXGI_ERROR_NOT_FOUND = 0x887A0002,
        DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED = 0x887A0023,
        DXGI_ERROR_REMOTE_OUTOFMEMORY = 0x887A0024,
        DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE = 0x887A0029,
        DXGI_ERROR_SDK_COMPONENT_MISSING = 0x887A002D,
        DXGI_ERROR_SESSION_DISCONNECTED = 0x887A0028,
        DXGI_ERROR_UNSUPPORTED = 0x887A0004,
        DXGI_ERROR_WAIT_TIMEOUT = 0x887A0027,
        DXGI_ERROR_WAS_STILL_DRAWING = 0x887A000A
    }

    internal static class DxgiErrorExtensions
    {
        public static bool IsDeviceLostError(this DXGI_ERROR error)
        {
            return error is DXGI_ERROR.DXGI_ERROR_DEVICE_REMOVED 
                or DXGI_ERROR.DXGI_ERROR_DEVICE_HUNG
                or DXGI_ERROR.DXGI_ERROR_DEVICE_RESET 
                or DXGI_ERROR.DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
        }
    }
}
